home *** CD-ROM | disk | FTP | other *** search
/ The X-Philes (2nd Revision) / The X-Philes Number 1 (1995).iso / xphiles / coding / 80x86 / code32.lzh / START32.ASM < prev    next >
Assembly Source File  |  1993-01-09  |  25KB  |  927 lines

  1. ; 386 Protected mode control program header.
  2. ; By Tran.
  3. ; Feel free to use this code in your own programs.
  4.  
  5.         .386p
  6.  
  7. LOWMIN  equ     0               ; minimum low memory needed to run (in K)
  8. EXTMIN  equ     0               ; minimum extended memory needed to run (in K)
  9. TSTAK   equ     400h            ; total stack size (in bytes)
  10. ISTAK   equ     80h             ; hardware IRQ safe stack size (in bytes)
  11.  
  12. desc    struc
  13. lml     dw      0
  14. bsl     dw      0
  15. bsm     db      0
  16. acc     db      0
  17. lmh     db      0
  18. bsh     db      0
  19. desc    ends
  20.  
  21. task    struc
  22. back            dd      0
  23. esp0            dd      0
  24. sp0             dd      10h
  25. esp1            dd      0
  26. sp1             dd      0
  27. esp2            dd      0
  28. sp2             dd      0
  29. ocr3            dd      0
  30. oeip            dd      0
  31. oeflags         dd      0
  32. oeax            dd      0
  33. oecx            dd      0
  34. oedx            dd      0
  35. oebx            dd      0
  36. oesp            dd      0
  37. oebp            dd      0
  38. oesi            dd      0
  39. oedi            dd      0
  40. oes             dd      0
  41. ocs             dd      0
  42. oss             dd      0
  43. ods             dd      0
  44. ofs             dd      0
  45. ogs             dd      0
  46. oldtr           dd      0
  47. iomap           dd      104 shl 16
  48. task    ends
  49.  
  50. code16  segment para stack use16 'stack'
  51. code16  ends
  52. code32  segment para public use32
  53. code32  ends
  54. codeend segment para public use32
  55. codeend ends
  56.  
  57.  
  58. code16  segment para stack use16 'stack'
  59.         assume cs:code16, ds:code16, ss:code16
  60.         org 0
  61.  
  62. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  63. ; 16 bit basic system data
  64. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  65. stak16  db      100h dup(?)
  66. stak16e label   near
  67. oldint1b        dd      ?
  68. nullint         db      0cfh
  69. errmsg0         db      'You must have a 386 or better to run this program!!!',7,'$'
  70. errmsg1         db      'This system is already in V86 mode!!!',7,'$'
  71. errmsg2         db      'You must have 640k low memory to run this program!!!',7,'$'
  72. errmsg3         db      'Not enough extended memory to run this program!!!',7,'$'
  73. errmsg4         db      'You must have VGA to run this program!!!',7,'$'
  74. errmsg5         db      'Not enough low memory to run this program!!!',7,'$'
  75. defidt          dw      3ffh, 0,0
  76.  
  77. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  78. ; 16 bit basic system code
  79. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  80. ;─────────────────────────────────────────────────────────────────────────────
  81. chek_VGA:                               ; Detect VGA or MCGA card
  82.         xor bx,bx
  83.         mov ax,01a00h
  84.         int 10h
  85.         cmp bl,7
  86.         jb short detectvgano
  87.         cmp bl,0ch
  88.         ja short detectvgano
  89.         ret
  90. detectvgano:
  91.         mov dx,offset errmsg4
  92.         jmp exit16err
  93. ;─────────────────────────────────────────────────────────────────────────────
  94. chek_processor:                         ; Detect if current processor 386
  95.         pushf
  96.         xor ah,ah
  97.         push ax
  98.         popf
  99.         pushf
  100.         pop ax
  101.         and ah,0f0h
  102.         cmp ah,0f0h
  103.         je short detectno386
  104.         mov ah,0f0h
  105.         push ax
  106.         popf
  107.         pushf
  108.         pop ax
  109.         and ah,0f0h
  110.         jz short detectno386
  111.         popf
  112.         ret
  113. detectno386:
  114.         mov dx,offset errmsg0
  115.         jmp short exit16err
  116. ;─────────────────────────────────────────────────────────────────────────────
  117. chek_virtual:                           ; Chek if already running in V86 mode
  118.         smsw ax
  119.         test al,1
  120.         jnz short detected_virtual86
  121.         ret
  122. detected_virtual86:
  123.         mov dx,offset errmsg1
  124.         jmp short exit16err
  125. ;─────────────────────────────────────────────────────────────────────────────
  126. chek_memory:                            ; Chek and get info on memory
  127.         int 12h
  128.         cmp ax,638
  129.         jb short notenoughlowmem
  130.         movzx eax,ax
  131.         shl eax,10
  132.         sub eax,ds:_code32a
  133.         mov ds:_lomemtop,eax
  134.         sub eax,ds:_lomembase
  135.         shr eax,10
  136.         cmp eax,LOWMIN
  137.         jb short notenoughlowmem2
  138.         mov ah,88h
  139.         int 15h
  140.         cmp ax,EXTMIN
  141.         jb short notenoughhighmem
  142.         mov ds:_totalextmem,ax
  143.         movzx eax,ax
  144.         shl eax,10
  145.         add eax,ds:_himembase
  146.         mov ds:_himemtop,eax
  147.         ret
  148. notenoughlowmem:
  149.         mov dx,offset errmsg2
  150.         jmp short exit16err
  151. notenoughlowmem2:
  152.         mov dx,offset errmsg5
  153.         jmp short exit16err
  154. notenoughhighmem:
  155.         mov dx,offset errmsg3
  156. ;─────────────────────────────────────────────────────────────────────────────
  157. exit16err:                              ; Exit program with message
  158.         mov ah,9
  159.         int 21h
  160.         mov ax,4cffh
  161.         int 21h
  162. ;═════════════════════════════════════════════════════════════════════════════
  163. start16:                                ; Program begins here
  164.         cli
  165.         mov sp,offset stak16e
  166.         mov ax,cs
  167.         mov ds,ax
  168.         call chek_VGA
  169.         call chek_processor
  170.         call chek_virtual
  171.  
  172.         mov eax,code16                  ; Calc misc memory pointers
  173.         shl eax,4
  174.         mov ds:_code16a,eax
  175.         mov eax,code32
  176.         shl eax,4
  177.         mov ds:_code32a,eax
  178.         mov ebx,codeend
  179.         shl ebx,4
  180.         sub ebx,eax
  181.         add ds:v86task.esp0,ebx
  182.         add ebx,TSTAK
  183.         mov ds:_lomembase,ebx
  184.         mov ebx,100000h
  185.         sub ebx,eax
  186.         mov ds:_himembase,ebx
  187.         call chek_memory
  188.  
  189.         xor ax,ax                       ; Disable CTRL+BREAK
  190.         mov es,ax
  191.         mov eax,es:[1bh*4]
  192.         mov oldint1b,eax
  193.         mov word ptr es:[1bh*4],offset nullint
  194.         mov word ptr es:[1bh*4+2],cs
  195.  
  196.         mov eax,ds:_code32a             ; Set up protected mode adresses
  197.         add dword ptr ds:gdt32a[2],eax
  198.         add dword ptr ds:idt32a[2],eax
  199.         mov ds:code32dsc.bsl,ax
  200.         mov ds:data32dsc.bsl,ax
  201.         add ds:v86taskdsc.bsl,ax
  202.         shr eax,8
  203.         mov ds:code32dsc.bsm,ah
  204.         mov ds:data32dsc.bsm,ah
  205.         add ds:v86taskdsc.bsm,ah
  206.         mov eax,ds:_code16a
  207.         mov ds:retrealc.bsl,ax
  208.         mov ds:retreald.bsl,ax
  209.         shr eax,8
  210.         mov ds:retrealc.bsm,ah
  211.         mov ds:retreald.bsm,ah
  212.  
  213.         lgdt fword ptr ds:gdt32a        ; Init protected mode
  214.         mov eax,cr0
  215.         or al,1
  216.         mov cr0,eax
  217.         db 0eah
  218.         dw start32,8
  219.  
  220. ;═════════════════════════════════════════════════════════════════════════════
  221. v86sys:                                 ; V86 interrupt
  222.         xor eax,eax
  223.         xor ebx,ebx
  224.         xor ecx,ecx
  225.         xor edx,edx
  226.         xor esi,esi
  227.         xor edi,edi
  228.         xor ebp,ebp
  229.         mov ax,cs:v86r_ax
  230.         mov bx,cs:v86r_bx
  231.         mov cx,cs:v86r_cx
  232.         mov dx,cs:v86r_dx
  233.         mov si,cs:v86r_si
  234.         mov di,cs:v86r_di
  235.         mov bp,cs:v86r_bp
  236.         db 0cdh
  237. v86sysintnum    db      ?
  238.         mov cs:v86r_ax,ax
  239.         mov cs:v86r_bx,bx
  240.         mov cs:v86r_cx,cx
  241.         mov cs:v86r_dx,dx
  242.         mov cs:v86r_si,si
  243.         mov cs:v86r_di,di
  244.         mov cs:v86r_bp,bp
  245.         mov cs:v86r_ds,ds
  246.         mov cs:v86r_es,es
  247.         pushf
  248.         pop ax
  249.         mov cs:v86r_flags,ax
  250.         int 0fdh
  251.  
  252. ;═════════════════════════════════════════════════════════════════════════════
  253. prerealmode:                            ; 16 bit protected mode to real mode
  254.         lidt fword ptr defidt
  255.         mov eax,cr0
  256.         and al,0feh
  257.         mov cr0,eax
  258.         db 0eah
  259.         dw realmode,code16
  260. realmode:                               ; Back in real mode
  261.         xor ax,ax                       ; Reenable CTRL+BREAK
  262.         mov es,ax
  263.         mov eax,cs:oldint1b
  264.         mov es:[1bh*4],eax
  265.         mov ax,cs                       ; Fix up regs and quit to DOS
  266.         mov ds,ax
  267.         mov es,ax
  268.         mov ss,ax
  269.         xor eax,eax
  270.         mov fs,ax
  271.         mov gs,ax
  272.         xor ebx,ebx
  273.         xor ecx,ecx
  274.         xor edx,edx
  275.         xor esi,esi
  276.         xor edi,edi
  277.         xor ebp,ebp
  278.         mov esp,offset stak16e+200h
  279.         mov ax,4c00h
  280.         int 21h
  281.  
  282.         dw      ?,?,?
  283. code16  ends
  284.  
  285.  
  286. code32  segment para public use32
  287.         assume cs:code32, ds:code32, ss:code32
  288.         org 0
  289.  
  290. extrn   _main:near
  291.  
  292. public  v86r_ax, v86r_bx, v86r_cx, v86r_dx, v86r_si, v86r_di, v86r_bp
  293. public  v86r_ds, v86r_es, v86r_flags, v86r_ah, v86r_al, v86r_bh, v86r_bl
  294. public  v86r_ch, v86r_cl, v86r_dh, v86r_dl
  295. public  _totalextmem, _code16a, _code32a, _hextbl, _lomembase, _lomemtop
  296. public  _himembase, _himemtop
  297.  
  298. public  _putdosmsg, _getvect, _setvect, _exit, _getmem, _getlomem, _gethimem
  299. public  _lomemsize, _himemsize, _ret
  300.  
  301. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  302. ; 32 bit basic system data
  303. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  304. gdt32           desc    <>
  305. code32dsc       desc    <0ffffh, 0, 0, 10011010b, 11001111b, 0>
  306. data32dsc       desc    <0ffffh, 0, 0, 10010010b, 11001111b, 0>
  307. zerodsc         desc    <0ffffh, 0, 0, 10010010b, 11001111b, 0>
  308. v86taskdsc      desc    <0ffffh, v86task, 0, 10001001b, 0, 0>
  309. retrealc        desc    <0ffffh, 0, 0, 10011010b, 0, 0>
  310. retreald        desc    <0ffffh, 0, 0, 10010010b, 0, 0>
  311. idt32           dw      exc0, 8, 08e00h, 0
  312.                 dw      exc1, 8, 08e00h, 0
  313.                 dw      exc2, 8, 08e00h, 0
  314.                 dw      exc3, 8, 08e00h, 0
  315.                 dw      exc4, 8, 08e00h, 0
  316.                 dw      exc5, 8, 08e00h, 0
  317.                 dw      exc6, 8, 08e00h, 0
  318.                 dw      exc7, 8, 08e00h, 0
  319.                 dw      exc8, 8, 08e00h, 0
  320.                 dw      exc9, 8, 08e00h, 0
  321.                 dw      exca, 8, 08e00h, 0
  322.                 dw      excb, 8, 08e00h, 0
  323.                 dw      excc, 8, 08e00h, 0
  324.                 dw      v86gen, 8, 08e00h, 0
  325.                 dw      exce, 8, 08e00h, 0
  326.                 dw      17 dup(unexp, 8, 08e00h, 0)
  327.                 dw      irq0, 8, 08e00h, 0
  328.                 dw      irq1, 8, 08e00h, 0
  329.                 dw      irq2, 8, 08e00h, 0
  330.                 dw      irq3, 8, 08e00h, 0
  331.                 dw      irq4, 8, 08e00h, 0
  332.                 dw      irq5, 8, 08e00h, 0
  333.                 dw      irq6, 8, 08e00h, 0
  334.                 dw      irq7, 8, 08e00h, 0
  335.                 dw      irq8, 8, 08e00h, 0
  336.                 dw      irq9, 8, 08e00h, 0
  337.                 dw      irqa, 8, 08e00h, 0
  338.                 dw      irqb, 8, 08e00h, 0
  339.                 dw      irqc, 8, 08e00h, 0
  340.                 dw      irqd, 8, 08e00h, 0
  341.                 dw      irqe, 8, 08e00h, 0
  342.                 dw      irqf, 8, 08e00h, 0
  343.                 dw      callv86sys, 8, 8e00h, 0
  344. gdt32a          dw      037h, gdt32,0
  345. idt32a          dw      187h, idt32,0
  346. v86task         task    <>
  347.                 db      2000h dup(0)
  348.  
  349. v86irqnum       db      ?               ; num of IRQ that ocurred in V86 mode
  350. v86r_ax         label   word            ; Virtual regs for virtual ints
  351. v86r_al         db      ?
  352. v86r_ah         db      ?
  353. v86r_bx         label   word
  354. v86r_bl         db      ?
  355. v86r_bh         db      ?
  356. v86r_cx         label   word
  357. v86r_cl         db      ?
  358. v86r_ch         db      ?
  359. v86r_dx         label   word
  360. v86r_dl         db      ?
  361. v86r_dh         db      ?
  362. v86r_si         dw      ?
  363. v86r_di         dw      ?
  364. v86r_bp         dw      ?
  365. v86r_ds         dw      ?
  366. v86r_es         dw      ?
  367. v86r_flags      dw      ?
  368.  
  369. oirqm21         db      ?               ; old low IRQ mask
  370. oirqma1         db      ?               ; old high IRQ mask
  371. _totalextmem    dw      ?               ; total extended memory present
  372. _code16a        dd      ?               ; offset of start of program from 0
  373. _code32a        dd      ?               ; offset of start of 32bit code from 0
  374. _lomembase      dd      ?               ; low mem base for allocation
  375. _lomemtop       dd      ?               ; top of low mem
  376. _himembase      dd      ?               ; high mem base for allocation
  377. _himemtop       dd      ?               ; top of high mem
  378. _hextbl         db      '0123456789ABCDEF'
  379.  
  380. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  381. ; 32 bit basic system code
  382. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  383. ;─────────────────────────────────────────────────────────────────────────────
  384. callv86sys:                             ; V86 INT AL
  385.         pushad
  386.         push es
  387.         push fs
  388.         push gs
  389.         mov bx,18h
  390.         mov es,bx
  391.         mov ebx,_code16a
  392.         mov es:v86sysintnum[ebx],al
  393.         push v86task.esp0
  394.         mov ecx,esp
  395.         sub esp,ISTAK
  396.         mov v86task.esp0,esp
  397.         xor eax,eax
  398.         push eax
  399.         push eax
  400.         mov ax,v86r_ds
  401.         push eax
  402.         mov ax,v86r_es
  403.         push eax
  404.         mov eax,codeend
  405.         push eax
  406.         shl eax,4
  407.         sub eax,_code32a
  408.         sub ecx,eax
  409.         push ecx
  410.         pushfd
  411.         pop eax
  412.         or eax,20000h
  413.         push eax
  414.         mov eax,code16
  415.         push eax
  416.         mov eax,offset v86sys
  417.         push eax
  418.         iretd
  419. retfromv86:
  420.         mov ax,10h
  421.         mov ds,ax
  422.         mov esp,v86task.esp0
  423.         add esp,ISTAK
  424.         pop v86task.esp0
  425.         pop gs
  426.         pop fs
  427.         pop es
  428.         popad
  429.         iretd
  430. ;─────────────────────────────────────────────────────────────────────────────
  431. v86gen:                                 ; General protection violation handler
  432.         test byte ptr [esp+14],2
  433.         jnz short v86genv86
  434.         pushad
  435.         mov dl,13
  436.         jmp exc
  437. v86genv86:
  438.         add esp,4
  439.         pushad
  440.         mov ax,18h
  441.         mov ds,ax
  442.         movzx ebx,word ptr [esp+36]
  443.         shl ebx,4
  444.         add ebx,[esp+32]
  445.         inc word ptr [esp+32]
  446.         mov al,[ebx]
  447.         mov dl,3
  448.         cmp al,0cch
  449.         je short v86int
  450.         cmp al,0ceh
  451.         ja exc
  452.         je short v86genv86ni
  453.         inc word ptr [esp+32]
  454.         mov dl,[ebx+1]
  455.         cmp dl,0fdh
  456.         jne short v86int
  457.         jmp retfromv86
  458. v86genv86ni:
  459.         mov dl,4
  460. v86int:                                 ; Do interrupt for V86 task
  461.         mov ax,18h
  462.         mov ds,ax
  463.         movzx ebx,dl
  464.         shl ebx,2
  465.         movzx edx,word ptr [esp+48]
  466.         shl edx,4
  467.         sub word ptr [esp+44],6
  468.         add edx,[esp+44]
  469.         mov ax,[esp+40]
  470.         mov [edx+4],ax
  471.         mov ax,[esp+36]
  472.         mov [edx+2],ax
  473.         mov ax,[esp+32]
  474.         mov [edx],ax
  475.         and word ptr [esp+40],0fcffh
  476.         mov eax,ds:[ebx]
  477.         mov [esp+32],ax
  478.         shr eax,16
  479.         mov [esp+36],ax
  480.         popad
  481.         iretd
  482.  
  483. ;─────────────────────────────────────────────────────────────────────────────
  484. exc0:                                   ; Exceptions
  485.     push ax
  486.     mov al,0
  487.     jmp irq
  488. exc1:
  489.     push ax
  490.     mov al,1
  491.         jmp irq
  492. exc2:
  493.     push ax
  494.     mov al,2
  495.         jmp irq
  496. exc3:
  497.     push ax
  498.     mov al,3
  499.         jmp irq
  500. exc4:
  501.     push ax
  502.     mov al,4
  503.         jmp irq
  504. exc5:
  505.     push ax
  506.     mov al,5
  507.         jmp irq
  508. exc6:
  509.         pushad
  510.         mov dl,6
  511.         jmp short exc
  512. exc7:
  513.     push ax
  514.     mov al,7
  515.         jmp irq
  516. exc8:
  517.         pushad
  518.         mov dl,8
  519.         jmp short exc
  520. exc9:
  521.         pushad
  522.         mov dl,9
  523.         jmp short exc
  524. exca:
  525.         pushad
  526.         mov dl,10
  527.         jmp short exc
  528. excb:
  529.         pushad
  530.         mov dl,11
  531.         jmp short exc
  532. excc:
  533.         pushad
  534.         mov dl,12
  535.         jmp short exc
  536. exce:
  537.         pushad
  538.         mov dl,14
  539.         jmp short exc
  540. unexp:                                  ; Unexpected interrupt
  541.         pushad
  542.         mov dl,0ffh
  543. exc:
  544.         cld                             ; Dump data
  545.         mov ax,10h
  546.         mov ds,ax
  547.         mov es,ax
  548.         mov fs,ax
  549.         mov ax,18h
  550.         mov gs,ax
  551.         mov al,0ffh
  552.         out 21h,al
  553.         out 0a1h,al
  554.         mov al,10h
  555.         mov v86r_ax,3
  556.         int 30h
  557.         mov edi,0b8000h+2*160
  558.         sub edi,_code32a
  559.         mov ebx,offset _hextbl
  560.         mov ecx,2
  561.         shl edx,24
  562.         mov ah,0fh
  563.         call excput
  564.         add edi,152
  565.         mov ah,0ah
  566.         mov ebp,8
  567. excl0:
  568.         pop edx
  569.         mov cl,8
  570.         call excput
  571.         dec ebp
  572.         jnz excl0
  573.         mov ebp,codeend
  574.         shl ebp,4
  575.         sub ebp,_code32a
  576.         add ebp,TSTAK
  577. excf0:
  578.         mov ah,0ch
  579. excl1:
  580.         pop edx
  581.         mov cl,8
  582.         call excput
  583.         cmp esp,ebp
  584.         jbe excf0
  585.         jmp _exit
  586. excput:
  587.         rol edx,4
  588.         mov al,dl
  589.         and al,0fh
  590.         xlat
  591.         stosw
  592.         loop excput
  593.         mov al,' '
  594.         stosw
  595.         stosw
  596.         ret
  597.  
  598. ;─────────────────────────────────────────────────────────────────────────────
  599. irq0:                                   ; Do IRQs
  600.         push ax
  601.         mov al,8
  602.         jmp short irq
  603. irq1:
  604.         push ax
  605.         mov al,9
  606.         jmp short irq
  607. irq2:
  608.         push ax
  609.         mov al,0ah
  610.         jmp short irq
  611. irq3:
  612.         push ax
  613.         mov al,0bh
  614.         jmp short irq
  615. irq4:
  616.         push ax
  617.         mov al,0ch
  618.         jmp short irq
  619. irq5:
  620.         push ax
  621.         mov al,0dh
  622.         jmp short irq
  623. irq6:
  624.         push ax
  625.         mov al,0eh
  626.         jmp short irq
  627. irq7:
  628.         push ax
  629.         mov al,0fh
  630.         jmp short irq
  631. irq8:
  632.         push ax
  633.         mov al,70h
  634.         jmp short irq
  635. irq9:
  636.         push ax
  637.         mov al,71h
  638.         jmp short irq
  639. irqa:
  640.         push ax
  641.         mov al,72h
  642.         jmp short irq
  643. irqb:
  644.         push ax
  645.         mov al,73h
  646.         jmp short irq
  647. irqc:
  648.         push ax
  649.         mov al,74h
  650.         jmp short irq
  651. irqd:
  652.         push ax
  653.         mov al,75h
  654.         jmp short irq
  655. irqe:
  656.         push ax
  657.         mov al,76h
  658.         jmp short irq
  659. irqf:
  660.         push ax
  661.         mov al,77h
  662. irq:
  663.         test byte ptr [esp+12],2
  664.         jnz short v86irq
  665.         push ds                         ; A real mode IRQ in protected mode
  666.         push ss
  667.         pop ds
  668.         int 30h
  669.         pop ds
  670.         pop ax
  671.         iretd
  672. v86irq:                                 ; An IRQ from V86 mode
  673.         mov ss:v86irqnum,al
  674.         pop ax
  675.         pushad
  676.         mov dl,ss:v86irqnum
  677.         jmp v86int
  678.  
  679. ;─────────────────────────────────────────────────────────────────────────────
  680. set8529vektorz:                         ; Set new IRQ vektor numbers
  681.         mov al,11h                      ;  BL - low vektor base #
  682.         out 20h,al                      ;  BH - high vektor base #
  683.         jmp short $+2
  684.         mov al,bl
  685.         out 21h,al
  686.         jmp short $+2
  687.         mov al,4h
  688.         out 21h,al
  689.         jmp short $+2
  690.         mov al,1h
  691.         out 21h,al
  692.         jmp short $+2
  693.         mov al,11h
  694.         out 0a0h,al
  695.         jmp short $+2
  696.         mov al,bh
  697.         out 0a1h,al
  698.         jmp short $+2
  699.         mov al,2h
  700.         out 0a1h,al
  701.         jmp short $+2
  702.         mov al,1h
  703.         out 0a1h,al
  704.         ret
  705.  
  706. ;─────────────────────────────────────────────────────────────────────────────
  707. enableA20:                              ; Enable gate A20
  708.         call enableA20o1
  709.         jnz short enableA20done
  710.         mov al,0d1h
  711.         out 64h,al
  712.         call enableA20o1
  713.         jnz short enableA20done
  714.         mov al,0dfh
  715.         out 60h,al
  716. enableA20o1:
  717.         mov ecx,20000h
  718. enableA20o1l:
  719.         jmp short $+2
  720.         in al,64h
  721.         test al,2
  722.         loopnz enableA20o1l
  723. enableA20done:
  724.         ret
  725.  
  726. ;═════════════════════════════════════════════════════════════════════════════
  727. start32:                                ; 32bit code begins here
  728.         lidt fword ptr cs:idt32a
  729.         mov ax,10h
  730.         mov ds,ax
  731.         mov es,ax
  732.         mov fs,ax
  733.         mov ss,ax
  734.         mov ax,18h
  735.         mov gs,ax
  736.         mov esp,_lomembase
  737.         mov ax,20h
  738.         ltr ax
  739.         pushfd
  740.         pop eax
  741.         or ah,30h
  742.         and ah,not 40h
  743.         push eax
  744.         popfd
  745.         in al,21h
  746.         mov oirqm21,al
  747.         or al,3
  748.         out 21h,al
  749.         in al,0a1h
  750.         mov oirqma1,al
  751.         mov bx,2820h
  752.         call set8529vektorz
  753.         call enableA20
  754.         sti
  755.         jmp _main
  756.  
  757. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  758. ; Some 'system' services
  759. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  760.  
  761. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  762. ; Exit to real mode
  763. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  764. _exit:
  765.         cli
  766.         mov bx,7008h
  767.         call set8529vektorz
  768.         mov al,oirqm21
  769.         out 21h,al
  770.         mov al,oirqma1
  771.         out 0a1h,al
  772.         mov ax,30h
  773.         mov ds,ax
  774.         mov es,ax
  775.         mov fs,ax
  776.         mov gs,ax
  777.         mov ss,ax
  778.         db 0eah
  779.         dw prerealmode,0,28h
  780.  
  781. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  782. ; Get interrupt vektor (0-30h)
  783. ; In:
  784. ;   BL - interrupt number
  785. ; Out:
  786. ;   EAX - 32 bit offset in code
  787. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  788. _getvect:
  789.         push ebx
  790.         movzx ebx,bl
  791.         mov ax,idt32[ebx*8+6]
  792.         shl eax,16
  793.         mov ax,idt32[ebx*8]
  794.         pop ebx
  795. _ret:                                   ; Generic RET for all procedures
  796.         ret
  797.  
  798. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  799. ; Set interrupt vektor (0-30h)
  800. ; In:
  801. ;   BL - interrupt number
  802. ;   EAX - 32 bit offset in code
  803. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  804. _setvect:
  805.         pushf
  806.         cli
  807.         push eax
  808.         push ebx
  809.         movzx ebx,bl
  810.         mov idt32[ebx*8],ax
  811.         shr eax,16
  812.         mov idt32[ebx*8+6],ax
  813.         pop ebx
  814.         pop eax
  815.         popf
  816.         ret
  817.  
  818. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  819. ; Allocate any mem, (first cheks low, then high)
  820. ; In:
  821. ;   EAX - size requested
  822. ; Out:
  823. ;   CF=1  - not enough mem
  824. ;     EAX - ?
  825. ;   CF=0  - memory allocated
  826. ;     EAX - linear pointer to mem
  827. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  828. _getmem:
  829.         push eax
  830.         call _getlomem
  831.         jnc short getmemd
  832.         pop eax
  833.         jmp short _gethimem
  834. getmemd:
  835.         add esp,4
  836.         ret
  837.  
  838. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  839. ; Allocate some low mem
  840. ; In:
  841. ;   EAX - size requested
  842. ; Out:
  843. ;   CF=1  - not enough mem
  844. ;     EAX - ?
  845. ;   CF=0  - memory allocated
  846. ;     EAX - linear pointer to mem
  847. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  848. _getlomem:
  849.         add eax,_lomembase
  850.         cmp eax,_lomemtop
  851.         ja short getmemerr
  852.         xchg eax,_lomembase
  853.         clc
  854.         ret
  855. getmemerr:
  856.         stc
  857.         ret
  858.  
  859. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  860. ; Allocate some high mem
  861. ; In:
  862. ;   EAX - size requested
  863. ; Out:
  864. ;   CF=1  - not enough mem
  865. ;     EAX - ?
  866. ;   CF=0  - memory allocated
  867. ;     EAX - linear pointer to mem
  868. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  869. _gethimem:
  870.         add eax,_himembase
  871.         cmp eax,_himemtop
  872.         ja short getmemerr
  873.         xchg eax,_himembase
  874.         clc
  875.         ret
  876.  
  877. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  878. ; Get amount of free low mem
  879. ; Out:
  880. ;   EAX - number of bytes free
  881. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  882. _lomemsize:
  883.         mov eax,_lomemtop
  884.         sub eax,_lomembase
  885.         ret
  886.  
  887. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  888. ; Get amount of free high mem
  889. ; Out:
  890. ;   EAX - number of bytes free
  891. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  892. _himemsize:
  893.         mov eax,_himemtop
  894.         sub eax,_himembase
  895.         ret
  896.  
  897. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  898. ; Put '$' terminated message to DOS
  899. ; In:
  900. ;   EDX -> message in low mem
  901. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  902. _putdosmsg:
  903.         push ax
  904.         push edx
  905.         add edx,_code32a
  906.         mov al,dl
  907.         and ax,0fh
  908.         shr edx,4
  909.         mov v86r_ds,dx
  910.         mov v86r_dx,ax
  911.         mov v86r_ah,9
  912.         mov al,21h
  913.         int 30h
  914.         pop edx
  915.         pop ax
  916.         ret
  917.  
  918. code32  ends
  919.  
  920.  
  921. codeend segment para public use32
  922.         assume cs:codeend
  923. stak32  label   near
  924. codeend ends
  925.         end     start16
  926.  
  927.